/*
 * rolling_hasher.h
 *
 *  Created on: 08/04/2011
 *      Author: Marcelo Juchem <juchem at gmail dot com>
 */

#ifndef ROLLING_HASHER_H_
#	define ROLLING_HASHER_H_

#include <cscience/queue/circular_array_queue.h>

namespace cscience {
namespace hash {

template <typename THasher>
class rolling_hasher
{
public:
	typedef THasher hasher_type;
	typedef typename hasher_type::hash_type hash_type;
	typedef typename hasher_type::value_type value_type;
	typedef size_t size_type;

private:
	hasher_type m_hasher;
	cscience::queue::circular_array_queue<value_type> m_queue;

public:
	rolling_hasher(size_type size):
		m_queue(size)
	{
	}

	size_type size() const
	{
		return this->m_queue.size();
	}

	rolling_hasher &operator <<(value_type const &in)
	{
		if(this->m_hasher.size() < this->m_queue.size())
		{
			this->m_hasher << in;
		}
		else
		{
			this->m_hasher.move(in, this->m_queue.dequeue());
		}

		this->m_queue.enqueue(in);

		return *this;
	}

	bool operator ==(hash_type const &hash) const
	{
		return this->m_hasher == hash;
	}

	bool operator !=(hash_type const &hash) const
	{
		return this->m_hasher != hash;
	}

	operator hash_type const &() const
	{
		return this->m_hasher;
	}
};

} // namespace hash {
} // namespace cscience {

#endif /* ROLLING_HASHER_H_ */
